<template>
  <el-table-column v-if="getVisible($attrs)" v-bind="$attrs">
    <template v-slot:header>
      <div @click.stop="() => false" style="display: inline-block">
        <!-- input -->
        <div v-if="proFilter.type === 'input'">
          <span>{{ $attrs.label }}</span>
          <el-popover trigger="click" :ref="$attrs.prop">
            <div class="d-flex">
              <el-input
                v-model="value"
                v-bind="attrs"
                v-on="proFilter.events"
                @keyup.enter.native="emitChange"
                @clear="emitChange"
              ></el-input>
              <div class="search-popver">
                <el-button
                  type="primary"
                  size="mini"
                  @click="emitChange"
                  icon="el-icon-search"
                ></el-button>
              </div>
            </div>
            <i
              @click="clickBtn"
              slot="reference"
              class="cursor-point el-icon-search"
              :class="isEmpty() ? '' : 'filtered-color'"
            ></i>
          </el-popover>
        </div>
        <!-- select -->
        <div v-if="proFilter.type === 'select'">
          <span>{{ $attrs.label }}</span>
          <el-popover trigger="click" :ref="$attrs.prop">
            <el-checkbox-group
              v-if="attrs.multiple"
              v-model="value"
              class="select-flex"
              v-bind="attrs"
              v-on="proFilter.events"
            >
              <el-checkbox
                :label="item.value"
                style="margin-bottom: 10px"
                v-for="(item, index) in attrs.options"
                :key="index"
              >
                {{ item.label }}</el-checkbox
              >
            </el-checkbox-group>
            <el-radio-group
              v-else
              class="select-flex"
              v-model="value"
              v-bind="attrs"
              v-on="proFilter.events"
            >
              <el-radio
                style="margin-bottom: 10px"
                :label="item.value"
                v-for="(item, index) in attrs.options"
                :key="index"
                >{{ item.label }}</el-radio
              >
            </el-radio-group>
            <div class="select-btn-flex">
              <el-button
                type="text"
                @click="emitChange"
                style="margin-right: 6px"
                >筛选</el-button
              >
              <el-button type="text" @click="resetChange" :disabled="isDisabled"
                >重置</el-button
              >
            </div>
            <i
              @click="clickBtn"
              slot="reference"
              class="cursor-point el-icon-arrow-down"
              :class="isEmpty() ? '' : 'filtered-color'"
            ></i>
          </el-popover>
        </div>
        <!-- cascader -->
        <div v-if="proFilter.type === 'cascader'">
          <span>{{ $attrs.label }}</span>
          <el-popover trigger="click" :ref="$attrs.prop">
            <div class="d-flex">
              <el-cascader
                v-model="value"
                v-bind="attrs"
                v-on="proFilter.events"
                :key="cascaderKey"
              ></el-cascader>
              <div class="">
                <el-button
                  type="text"
                  @click="emitChange"
                  style="margin-left: 10px"
                  >筛选</el-button
                >
                <el-button
                  type="text"
                  @click="resetChange"
                  style="margin-left: 10px"
                  :disabled="isDisabled"
                  >重置</el-button
                >
              </div>
            </div>
            <i
              @click="clickBtn"
              slot="reference"
              class="cursor-point el-icon-arrow-down"
              :class="isEmpty() ? '' : 'filtered-color'"
            ></i>
          </el-popover>
        </div>
        <!-- date -->
        <div v-if="isDateType(proFilter.type)">
          <span>{{ $attrs.label }}</span>
          <el-popover trigger="click" :ref="$attrs.prop">
            <div class="d-flex">
              <el-date-picker
                v-model="value"
                v-bind="attrs"
                v-on="proFilter.events"
                @change="emitChange"
              ></el-date-picker>
            </div>
            <i
              @click="clickBtn"
              slot="reference"
              class="cursor-point el-icon-date"
              :class="isEmpty() ? '' : 'filtered-color'"
            ></i>
          </el-popover>
        </div>
        <!-- custom -->
        <div v-if="proFilter.type === 'custom'">
          <span>{{ $attrs.label }}</span>
          <el-popover trigger="click" :ref="$attrs.prop">
            <div class="d-flex">
              <slot name="header" :value="value"></slot>
              <!-- <el-input
                v-model="value"
                v-bind="attrs"
                v-on="proFilter.events"
                @keyup.enter.native="emitChange"
                @clear="emitChange"
              ></el-input>
              <div class="search-popver">
                <el-button
                  type="primary"
                  size="mini"
                  @click="emitChange"
                  icon="el-icon-search"
                ></el-button>
              </div> -->
            </div>
            <i
              @click="clickBtn"
              slot="reference"
              class="cursor-point iconfont icon-filter"
              :class="isEmpty() ? '' : 'filtered-color'"
            ></i>
          </el-popover>
        </div>
      </div>
    </template>
    <!-- 同时存在slot与formatter时，formatter优先 -->
    <template v-slot="scope" v-if="!$attrs.formatter">
      <slot
        name="content"
        :row="scope.row"
        :$index="scope.$index"
        :value="
          proFilter.type === 'select'
            ? getCellvalue(scope.row[$attrs.prop])
            : scope.row[$attrs.prop]
        "
      >
        <span v-if="proFilter.type === 'select'">
          {{
            getCellvalue(scope.row[$attrs.prop])
              .map(option => option.label)
              .toString()
          }}
        </span>
        <span v-else-if="proFilter.type === 'cascader'">
          <el-cascader
            class="readonlycascader"
            :value="scope.row[$attrs.prop]"
            v-bind="attrs"
            :disabled="true"
            :key="cascaderKey"
          ></el-cascader>
        </span>
        <span v-else>
          {{ scope.row[$attrs.prop] }}
        </span>
      </slot>
    </template>
  </el-table-column>
</template>
<script>
export default {
  inheritAttrs: false,
  name: "el-table-column-pro",
  props: {
    // 筛选表单配置
    proFilter: {
      type: Object,
      required: true
      /*{
        type:"",  类型：input|select|cascader|DatePicker包含类型
        attrs:"", 属性：multiple: 控制多选单选
        events:"" 方法：
      }
    */
    },
    // 筛选value值
    proValue: {
      required: true
    },
    // 是否显示列
    visible: {
      type: Boolean,
      default: true
    },
    // 筛选回调函数
    proCallback: {
      type: Function
    }
  },
  data() {
    return {
      value: this.proValue,
      attrs: this.getAttrs(),
      cascaderKey: false,
      vNodes: []
    };
  },
  watch: {
    "proFilter.attrs": {
      handler(value) {
        const { proFilter, cascaderKey } = this;
        if (value.options) {
          this.attrs = this.getAttrs();
          if (proFilter.type === "cascader") {
            this.cascaderKey = !cascaderKey;
          }
        }
      },
      deep: true
    }
  },
  computed: {
    isDisabled() {
      const { getType, value } = this;
      const valueType = getType(value);
      if (
        valueType === "Number" ||
        (valueType === "Array" && value.length) ||
        (valueType === "String" && value) ||
        valueType === "Boolean"
      ) {
        return false;
      } else {
        return true;
      }
    }
  },
  methods: {
    clickBtn() {
      //手动触发其关闭方法  doClose（）
      // console.log(this.$parent.$slots.default, this, this.$refs, "点击了");
      if (this.vNodes.length > 0) {
        for (let i = 0; i < this.vNodes.length; i++) {
          if (
            this.vNodes[i].$refs[this.vNodes[i].$attrs.prop] &&
            this.$attrs.prop !== this.vNodes[i].$attrs.prop
          ) {
            this.vNodes[i].$refs[this.vNodes[i].$attrs.prop].doClose();
          }
        }
      }
    },

    getType(val) {
      return Object.prototype.toString.call(val).slice(8, -1);
    },
    getCellvalue(value) {
      const { attrs, getType } = this;
      const type = getType(value);
      if (type === "Array") {
        return value.map(val => {
          const option = attrs.options.find(item => item.value === val);
          return option ? [option] : [{ label: "" }];
        });
      } else {
        const option = attrs.options.find(item => item.value === value);
        return option ? [option] : [{ label: "" }];
      }
    },
    isDateType(type) {
      const dateMap = [
        "year",
        "month",
        "date",
        "dates",
        "week",
        "datetime",
        "datetimerange",
        "daterange",
        "monthrange"
      ];
      return dateMap.includes(type);
    },
    isEmpty() {
      const { proFilter, proValue } = this;
      const emptyMap = ["[]", "", "undefined", "null"];
      if (this.proFilter.empty) {
        emptyMap.push(this.proFilter.empty.value + "");
      }
      return emptyMap.includes(proValue + "");
    },
    getAttrs() {
      const { proFilter } = this;
      if (proFilter.type === "input") {
        return Object.assign(
          {
            placeholder: "",
            clearable: true
          },
          proFilter.attrs
        );
      }
      if (proFilter.type === "select") {
        return Object.assign(
          {
            options: []
          },
          proFilter.attrs
        );
      }
      if (proFilter.type === "cascader") {
        return Object.assign(
          {
            placeholder: "",
            options: []
          },
          proFilter.attrs
        );
      }
      if (this.isDateType(proFilter.type)) {
        return Object.assign(
          {
            type: proFilter.type
          },
          proFilter.attrs
        );
      }
    },
    emitChange() {
      let emptyValue = this.value;
      if (this.proFilter.empty && emptyValue === "") {
        emptyValue = this.proFilter.empty.value;
      }
      this.$emit("update:proValue", emptyValue);
      this.proCallback();
      this.$refs[this.$attrs.prop].doClose();
    },
    resetChange() {
      if (this.attrs.multiple) {
        this.value = [];
      } else {
        // 这里 单选 查全部的数据传 "" 给后端，极个别的后端可能会要求传 -1
        this.value = "";
      }
      this.emitChange();
    },
    getVisible(attrs) {
      const columnsArr = this.$parent.$attrs.columnsArr;
      if (columnsArr) {
        // console.log(val.prop);
        for (let i = 0; i < columnsArr.length; i++) {
          if (columnsArr[i].prop === attrs.prop) {
            return columnsArr[i].visible;
          }
        }
      } else {
        return this.visible;
      }
    }
  },
  mounted() {
    //通过$parent获取它的父组件里全部的筛选组件
    this.vNodes = [];
    this.$parent.$slots.default.forEach(vNode => {
      if (vNode.tag && vNode.tag.includes("el-table-column-pro")) {
        this.vNodes.push(vNode.child);
      }
    });
  }
};
</script>
<style scoped>
.cursor-point.filtered-color {
  color: #00b2ff;
  font-weight: bold;
  transform: scale(1.1);
}
.d-flex {
  display: flex;
}
.search-popver {
  margin-left: 5px;
}
.cursor-point {
  cursor: pointer;
  color: #bfbfbf;
  padding: 3px;
  outline: none;
}
.cursor-point:not(.filtered-color):hover {
  color: #7e7e7e;
}
.select-flex {
  border-bottom: 1px solid #dcdfe6;
  display: flex;
  flex-direction: column;
}
.select-btn-flex {
  display: flex;
  justify-content: flex-end;
}
.select-btn-flex .el-button {
  padding-bottom: 2px;
}
:deep(.readonlycascader input) {
  border: 0;
  background-color: inherit !important;
  color: inherit !important;
  cursor: auto !important;
}
:deep(.readonlycascader .el-input__suffix) {
  display: none;
}
@font-face {
  font-family: "iconfont";
  src: url("data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAKQAAsAAAAABkgAAAJEAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCCcApMYwE2AiQDCAsGAAQgBYRtBzUbjgXIHpIkQUkVRSEKOBkGECKo1qqsnp49YFQXJwkkPpEjUO5ZOCBhAY1jSUbc9fu1PfNQd4Z63riEWdL+Zd+3Z/P+Ys0sREJmSAVC44iQiOTdx//B5fQnUCDzgHKbY/CYgIGlgY01KbISyrhh7IIXeJxArUF9ha2NvUOoy+xxgbiZRB7UCx5ZZvFqodKwNEPcV6pOT+kD96Lvx38LUQ2SsgC7aP/yeghLf3aSSpdHl84HCC8BrS5RYB7IxPHGyK6SYJSS2kjZKDhWMPgz5gc6cVS1YH8dzq0H/ZDzTFyP96i5CeSksx3omXQrqbYZXL6q67y8iUI77z592XOmc+719fnFbku3gld/3Wn9/Y2du3MXvtztWMM/K56kH4HgrW/fLvWW/qvrygDfyhciVTbMRvVerMHf4A5syAbf1qascRttSfuksQm1anEEO1p9T1V0nDoRqnXcgK3KQAaFauNoJuehVGcRKqqtQq05m6vrtHFKIjeAWXcAQrN3SBp9gEKzTzSTcyh1+oOK5iig1slo27LOZFxrbjrymEL0LzAJjBaunptx/j5FJ9JzeX5EPSaXJ36cDMfl+CZpckvMyE+jKbNA4YzCDXAaSWnQOpNSwMOY2c5GI9H0pmFgFDRtcoiHkRDyXUCJgKGJoD1rVj6/j0ROSB7XUVJnPUacXNI9mhgaD0A3JXpQyaO8kjsVmWJMQIJjKGgDDCKSZCDbPChFAmwonhCyZkZOKzFUMtxepn4gm1VgK1M4PUpQdzmRTG4QmiUAAAA=")
    format("woff2");
}
.iconfont {
  font-family: "iconfont" !important;
  font-size: inherit;
  font-style: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
.icon-filter:before {
  content: "\e8ff";
}
</style>
